package crud.client.dialog;

import java.util.ArrayList;
import java.util.List;

import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;

import crud.client.constant.CstExport;
import crud.client.constant.CstTailleChamp;
import crud.client.data.Colonne;
import crud.client.data.Donnee;
import crud.client.data.LigneDonnee;
import crud.client.data.Table;
import crud.client.service.ServiceLocator;
import crud.client.util.GenericCallback;

public class TableListGrid extends ListGrid
{
	private List<LigneDonnee> ligneDonneToDeleteList = new ArrayList<LigneDonnee>();
	
	private List<Colonne> colonneList;
	private List<Colonne> pkList;
	private List<Colonne> nonPkList;
	private Table table;

	
	public TableListGrid(Table table, List<Colonne> colonneList)
	{
		this.table = table;
		this.colonneList = colonneList;
		this.setAlternateRecordStyles(true);
		
		// La liste de données et ses champs
		ListGridField ListGridFieldTable[] = new ListGridField[colonneList.size()];
		for (int cp = 0; cp <= colonneList.size() - 1; cp++)
		{
			Colonne colonne = colonneList.get(cp);
			ListGridField colonneField = colonne.getListGridFactory().newListGridField(colonne);
			colonneField.setWidth(calculateDataGridFieldWidth(colonne));
			
			if (colonne.isPk())
			{
				colonneField.setIcon("/img/pk.jpeg");
			}
			
			ListGridFieldTable[cp] = colonneField;
		}
		setFields(ListGridFieldTable);
		setWidth(calculateDataGridWidth(colonneList));

	}

	public List<Colonne> getColonneList()
	{
		return colonneList;
	}
	
	public List<Colonne> getPkList()
	{
		if (pkList == null)
		{
			pkList = new ArrayList<Colonne>();

			for (Colonne colonne : getColonneList())
			{
				if (colonne.isPk() == true)
				{
					pkList.add(colonne);
				}
			}
		}

		return pkList;
	}

	public List<Colonne> getNonPkList()
	{
		if (nonPkList == null)
		{
			nonPkList = new ArrayList<Colonne>();

			for (Colonne colonne : getColonneList())
			{
				if (colonne.isPk() == false)
				{
					nonPkList.add(colonne);
				}
			}
		}

		return nonPkList;
	}


	public void reloadData()
	{
		ligneDonneToDeleteList.clear();
		
		GenericCallback<List<LigneDonnee>> donneeCallback = new GenericCallback<List<LigneDonnee>>()
		{

			@Override
			public void onSuccess(List<LigneDonnee> donneeParLigneList)
			{
				// Suppression des lignes existantes
				setRecords(new ListGridRecord[0]);

				// Ajout des nouvelles lignes
				for (LigneDonnee ligneDonnee : donneeParLigneList)
				{
					addData(ligneDonnee);
				}

			}
		};
		ServiceLocator.getServiceBase().getDonneeLineList(table, colonneList, donneeCallback);
	}

	public void addData(LigneDonnee ligneDonnee)
	{
		addOrReplaceData(ligneDonnee, (Integer) null);
	}
	
	public void addOrReplaceData(LigneDonnee ligneDonnee, Integer lineNumber)
	{
		List<Donnee> donneeList = ligneDonnee.getDonneeList();

		// Création de l'enregistrement, à proprement parler
		ListGridRecord record = null; 
		
		if (lineNumber != null )
		{
			record = getRecord(lineNumber);
		}
		else
		{
			record = new ListGridRecord();
			addData(record);
		}
		
		for (Donnee donnee : donneeList)
		{
			donnee.setValueInRecord(record, this);
		}
		//refreshFields();
		setRecords(getRecords());	
	}

	public void addOrReplaceData(LigneDonnee ligneDonnee, String oldPk)
	{
		List<Donnee> donneeList = ligneDonnee.getDonneeList();

		// Création de l'enregistrement, à proprement parler
		ListGridRecord record = null; 
		
		if (oldPk != null && !oldPk.isEmpty())
		{
			record = getCorrespondingRecord(oldPk);
		}
		else
		{
			record = new ListGridRecord();
			addData(record);
		}
		
		for (Donnee donnee : donneeList)
		{
			donnee.setValueInRecord(record, this);
		}
		//refreshFields();
		setRecords(getRecords());
	}

	public ListGridRecord getCorrespondingRecord(String selectedPk)
	{
		for (int cp = 0; cp <= getTotalRows() - 1; cp++)
		{
			ListGridRecord record = (ListGridRecord) getRecord(cp);
			
			if (extractPK(record).equals(selectedPk))
			{
				return record;
			}
		}
		
		return null;
	}

	public ListGridRecord getCorrespondingRecord(LigneDonnee ligneDonnee)
	{
		String pk = extractPK(ligneDonnee);
		for (int cp = 0; cp <= getTotalRows() - 1; cp++)
		{
			ListGridRecord record = (ListGridRecord) getEditedRecord(cp);
			
			if (extractPK(record).equals(pk))
			{
				return record;
			}
		}
		
		return null;
	}

	public LigneDonnee getCorrespondingLigneDonnee(String selectedPk)
	{
		ListGridRecord record = getCorrespondingRecord(selectedPk);
		
		if (record == null)
		{
			return null;
		}
		return getLigneDonnee(record);
	}
	
	public LigneDonnee getLigneDonnee(ListGridRecord record)
	{
		LigneDonnee ligneDonnee = new LigneDonnee();
		ligneDonnee.setLineNumber(getRecordIndex(record));
		for (Colonne colonne : colonneList)
		{
			ligneDonnee.add(Donnee.extractDonneeFromRecord(colonne, record));
		}
		
		return ligneDonnee;
	}
	public String extractPK(ListGridRecord record)
	{
		String pk = "";

		for (Colonne colonne : getPkList())
		{
			pk += record.getAttribute(colonne.getCodeColonne());
		}

		return pk;
	}

	public String extractPK(LigneDonnee ligneDonnee)
	{
		String pk = "";

		for (Colonne colonne : getPkList())
		{
			Donnee donnee = ligneDonnee.getDonnee(colonne);
			if (donnee != null && donnee.getDataView().getLabel() != null)
			{
				pk += ligneDonnee.getDonnee(colonne).getDataView().getLabel();
			}
		}

		return pk;
	}

	public void removeDataByPk(String pkToRemove)
	{
		// Validation par les validateurs
		for (int cp = 0; cp <= getTotalRows() - 1; cp++)
		{
			ListGridRecord record = getRecord(cp);
			if (pkToRemove.equals(extractPK(record)))
			{
				ligneDonneToDeleteList.add(getLigneDonnee(record));
				removeData(record);
				return;
			}
		}
	}

	public Table getTable()
	{
		return table;
	}
	
	
	public static int calculateDataGridWidth(List<Colonne> colonneList)
	{
		int width = 3;
		for (Colonne colonne : colonneList)
		{
			width += calculateDataGridFieldWidth(colonne);
		}

		if (width <= CstTailleChamp.LARGEUR_MAX_LISTE)
		{
			return width;
		}
		else
		{
			return 600;
		}
	}

	public static int calculateDataGridFieldWidth(Colonne colonne)
	{
		int width = 8 * colonne.getLibelle().length() + 10;
		
		if (colonne.isPk())
		{
			width += 10;
		}
		
		if (width >= 60)
		{
			return width;
		}
		else
		{
			return 60;
		}
		 
	}

	public List<LigneDonnee> getLigneDonneToDeleteList()
	{
		return ligneDonneToDeleteList;
	}

	public void setLigneDonneToDeleteList(List<LigneDonnee> ligneDonneToDeleteList)
	{
		this.ligneDonneToDeleteList = ligneDonneToDeleteList;
	}

	public String getExportHeader(String separator)
	{
		String header = "";
		for (Colonne colonne : colonneList)
		{
			header += colonne.getLibelle().replaceAll("[" + separator + "]", "");
			header += separator;
		}
		
		return header;
	}
	
	public String getExportBody(int lineNumber, String separator)
	{
		String body = "";
		ListGridRecord record = getRecord(lineNumber);
		for (Colonne colonne : colonneList)
		{
			String column = record.getAttributeAsString(colonne.getCodeColonne());
			
			if (column == null)
			{
				column = "";
			}
			body += column.replaceAll("[" + separator + "]", "") + separator;
		}
		
		return body ;
	}

	public String getExportBody(String separator)
	{
		String body = "";
		for (int cp = 0; cp <= getTotalRows() - 1; cp++)
		{
			body += getExportBody(cp, separator) + CstExport.RETOUR_LIGNE;
		}
		return body;
	}

	public String getExport(String separator)
	{
		String export = getExportHeader(separator) + CstExport.RETOUR_LIGNE + getExportBody(separator);
		export = export.replaceAll("[=]", "").replaceAll("[&]", "").replaceAll("[\"]", "").replaceAll("[\r]", "").replaceAll("[\n]", "");
		return export;
	}

}
